package com.yenlien.traceyun.plant.dock_device.xinfengxiang;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yenlien.traceyun.business.dao.BaseSoilDao;
import com.yenlien.traceyun.business.entity.BaseSoilEquipment;
import com.yenlien.traceyun.business.entity.Equipment;
import com.yenlien.traceyun.business.service.EquipmentService;
import com.yenlien.traceyun.common.utils.HttpUtil;
import com.yenlien.traceyun.common.utils.Tools;
import com.yenlien.traceyun.plant.dao.DevAlarmDao;
import com.yenlien.traceyun.plant.dao.DevThresholdDao;
import com.yenlien.traceyun.plant.dao.XinFengXiangDao;
import com.yenlien.traceyun.plant.entity.DevAlarm;
import com.yenlien.traceyun.plant.entity.DevThreshold;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.yenlien.traceyun.plant.dock_device.DevState.EQU_MANUFACTURER_XFX;

/**
 * @author jialong
 * @date 2021/03/31
 * @description: 定时获取数据       安装了 新风向(  sass   http://app.cpzsyun.com/  和  果园二期http://grove.cpzsyun.com:81/  ) 的气象设备 该定时任务才需要执行，
 **/

@Slf4j
@Component
public class XinFengXiangGetData {

    @Autowired
    private EquipmentService equipmentService;

    @Autowired
    private XinFengXiangDao xinFengXiangDao;

    @Autowired
    private BaseSoilDao baseSoilDao;

    @Autowired
    private DevThresholdDao devThresholdDao;

    @Autowired
    private DevAlarmDao devAlarmDao;

    @Value("${xinFengXiang.url}")
    private String url;


//    @Scheduled(fixedRate = TWO_HOURS, initialDelay = TWO_HOURS)
//    @Scheduled(fixedRate = fixedRate)
    public void getData() {
        // 获取所有设备ID和序列号(序列号即对方平台的设备ID) 一个设备下对应多个传感器
        List<Equipment> equipmentList = equipmentService.findByManufacturer(EQU_MANUFACTURER_XFX);
        if (CollectionUtils.isEmpty(equipmentList)) {
            return;
        }
        //获取设备与地块的对应关系,
        List<BaseSoilEquipment> equipmentBaseSoilList = equipmentService.getEquipmentBaseSoil(equipmentList.stream().map(Equipment::getId).collect(Collectors.toList()));
        if (CollectionUtils.isEmpty(equipmentBaseSoilList)) {
            return;
        }
        // 筛选出平台已绑定的设备
        ArrayList<Equipment> equipmentArrayList = new ArrayList<>();
        for (BaseSoilEquipment baseSoilEquipment : equipmentBaseSoilList) {
            for (Equipment equipment : equipmentList) {
                if (StringUtils.isNotBlank(baseSoilEquipment.getEquipmentId()) && StringUtils.isNotBlank(equipment.getId())) {
                    if (baseSoilEquipment.getEquipmentId().equals(equipment.getId())) {
                        equipmentArrayList.add(equipment);
                    }
                } else {
                    log.error("数据异常, 设备ID为空: {}", baseSoilEquipment.getEquipmentId());
                }
            }
        }
        // 由于没有提供一次获取多个设备的接口，所以这里只能循坏请求获取每个设备的数据
        equipmentArrayList.forEach(equipment -> {
            JSONObject result = JSONObject.parseObject(HttpUtil.getDataFromUrl(url + equipment.getSerial()));     // 获取数据并解析
            if (result == null) {
                return;
            }
            if ("200".equals(result.get("statusCode")) && "success".equals(result.get("message"))) {
                JSONArray jsonArray = result.getJSONArray("entity");
                if (jsonArray == null || jsonArray.size() == 0) {
                    log.error("该序列号对应的设备在新风向平台不存在, 序列号: {}", equipment.getSerial());
                    return;
                }
                List<CurrentDataEntity> lists = new ArrayList<>();                                                  // 气象数据
                jsonArray.forEach(item -> lists.add(JSON.parseObject(item.toString(), CurrentDataEntity.class)));
                String deviceId = String.valueOf(result.get("deviceId"));                                        // 跟据设备序列号(对方平台设备ID)找到设备ID并获取地块ID
                final String[] equipmentId = {null};              // 自己平台的设备ID
                final String[] baseOilId = {null};          // 地块ID

                for (Equipment e : equipmentArrayList) {
                    if (deviceId.equals(e.getSerial())) {
                        equipmentId[0] = e.getId();
                        break;
                    }
                }
                if (equipmentId[0] != null) {
                    // 如果设备与地块不是一对一，则这种方式可能存在问题，可通过数组或集合去实现一对多
                    for (BaseSoilEquipment x : equipmentBaseSoilList) {
                        if (equipmentId[0].equals(x.getEquipmentId())) {
                            baseOilId[0] = x.getBaseSoilId();
                            break;
                        }
                    }
                } else {
                    log.error("对方返回的设备序列号与我方设备ID没有关联, 序列号: {}", deviceId);
                    return;
                }
                // 组装数据并入库
                List<XinFengXiang> xinFengXiangList = new ArrayList<>();
                for(CurrentDataEntity x : lists){
                    if(!"3276.7".equals(x.getEValue())){    // 该值代表无数据
                        XinFengXiang xinFengXiang = new XinFengXiang(
                                equipmentId[0], deviceId, baseOilId[0], equipment.getName(), equipment.getCompanyId(),
                                x.getDatetime(), x.getEUnit(), x.getEValue(), x.getEKey(), x.getEName(), x.getENum(), new Date());
                        xinFengXiangList.add(xinFengXiang);
                    }
                }
                // 添加预警信息
                List<DevAlarm> alarmList = new ArrayList<>();
                Date date = new Date();
                String baseSoilName = baseSoilDao.getNameByEquId(equipment.getId());
                List<DevThreshold> devThresholdList = devThresholdDao.getByCompIdAndEquId(equipment.getCompanyId(), equipment.getSerial());
                for(XinFengXiang xinFengXiang : xinFengXiangList){
                    List<DevThreshold> thresholdList = devThresholdList.stream().filter(x -> x.getType().equals(xinFengXiang.getEName())).collect(Collectors.toList());
                    if(CollectionUtils.isEmpty(thresholdList)){
                        continue;
                    }
                    DevThreshold devThreshold = thresholdList.get(0);
                    if(devThreshold != null){
                        Double high = devThreshold.getHigh();
                        Double low = devThreshold.getLow();
                        Double paramVal = Double.valueOf(xinFengXiang.getEValue());
                        if(paramVal > high || paramVal < low){
                            DevAlarm devAlarm = new DevAlarm();
                            devAlarm.setDevId(equipment.getSerial());
                            devAlarm.setDevName(equipment.getName());
                            devAlarm.setDevType(equipment.getType());
                            devAlarm.setParamName(xinFengXiang.getEName());
                            devAlarm.setVal(xinFengXiang.getEValue()  + xinFengXiang.getEUnit());
                            devAlarm.setThreshold(low + "~" + high + xinFengXiang.getEUnit());
                            devAlarm.setCompId(equipment.getCompanyId());
                            devAlarm.setHandleState("1");
                            devAlarm.setBaseSoilName(baseSoilName);
                            devAlarm.setCreateTime(Tools.DATE_TIME_FORMAT.format(date));
                            devAlarm.setAlarmType("1");
                            if(paramVal > high){
                                devAlarm.setTitle(xinFengXiang.getEName() + "高于最大值: " + high);
                            }
                            if(paramVal < low){
                                devAlarm.setTitle(xinFengXiang.getEName() + "低于最小值: " + low);
                            }
                            // 判断该设备该参数当天有没有生成预警数据
                            if(CollectionUtils.isEmpty(devAlarmDao.getIdByParamNameAndDevId(xinFengXiang.getEName(), equipment.getSerial()))){
                                alarmList.add(devAlarm);
                            }
                        }
                    }
                }
                devAlarmDao.saveAll(alarmList);
                checkAllIsSuccess(xinFengXiangDao.saveAll(xinFengXiangList));
            } else {
                log.error("请求不成功, 返回结果: {}", result.toString());
            }
        });
    }

    /**
     * 根据有没有回填ID来判断是否插入成功
     */
    public void checkAllIsSuccess(List<XinFengXiang> lists) {
        for (XinFengXiang xinFengXiang : lists) {
            if (xinFengXiang.getId() == null) {
                log.error("插入新风向数据失败, 数据：{}", xinFengXiang);
            }
        }
    }

}
